﻿using SF.Express.Sdk.Helper;
using SF.Express.Sdk.Request;
using SF.Express.Sdk.Response;
using System;
using System.IO;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;

namespace SF.Express.Sdk
{
    public class SFExpressClient : ISFExpressClient
    {
        /// <summary>
        /// 接口地址
        /// </summary>
        public string ServerUrl = "https://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService";

        public T Execute<T>(BaseRequest<T> request) where T : BaseResponse
        {
            //
            string requestXml = XmlHelper.Serialize(o: request);
            string verifyCode = VerifyCodeHelper.Compute(s: requestXml + request.CheckWord);
            Dictionary<string, string> httpParams = new Dictionary<string, string>();
            httpParams.Add(key: "xml", value: requestXml);
            httpParams.Add(key: "verifyCode", value: verifyCode);
            string s = HttpHelper.BuildQuery(parameters: httpParams);
            //byte[] data = Encoding.UTF8.GetBytes(s: "xml=&verifyCode=");
            byte[] data = Encoding.UTF8.GetBytes(s: s);

            //
            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;
            try
            {
                httpWebRequest = HttpWebRequest.Create(requestUriString: ServerUrl) as HttpWebRequest;
                httpWebRequest.Method = "POST";
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                httpWebRequest.Timeout = 20 * 1000;
                httpWebRequest.KeepAlive = false;
                httpWebRequest.ServicePoint.ConnectionLimit = 512;
                httpWebRequest.ContentLength = data.Length;
                using (Stream stream = httpWebRequest.GetRequestStream())
                {
                    stream.Write(buffer: data, offset: 0, count: data.Length);
                }

                httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
                Encoding encoding = Encoding.GetEncoding(name: httpWebResponse.CharacterSet);
                using (Stream stream = httpWebResponse.GetResponseStream())
                {
                    XmlDocument xmlDocument = new XmlDocument();
                    xmlDocument.Load(inStream: stream);
                    string xmlString = xmlDocument.OuterXml;
                    T response = Activator.CreateInstance<T>();
                    response = XmlHelper.Deserialize<T>(s: xmlString);
                    return response;
                }
            }
            catch (ThreadAbortException ex)
            {
                Thread.ResetAbort();
                throw ex;
            }
            catch (WebException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (httpWebResponse != null)
                {
                    httpWebResponse.Close();
                }
                if (httpWebRequest != null)
                {
                    httpWebRequest.Abort();
                }
            }
        }
    }
}
